<template>
  <div>
    <a-layout>
      <a-layout-header class="header"
        ><a-space>
          <span>服务器：</span>
          <a-input v-model:value="formModel.server" />
          <span>端口：</span>
          <a-input v-model:value="formModel.port" />
          <span>用户名：</span>
          <a-input v-model:value="formModel.username" />
          <span>密码：</span>
          <a-input-password v-model:value="formModel.password" />
          <a-button type="primary" @click="connect">连接</a-button>
        </a-space></a-layout-header
      >
      <a-layout-content class="a-layout-content"
        ><section>
          <div id="log" style="margin: 10px auto">
            <div class="console" id="terminal"></div>
          </div> </section
      ></a-layout-content>
    </a-layout>
  </div>
</template>

<script setup>
  import 'xterm/css/xterm.css'
  import { Terminal } from 'xterm'
  import { FitAddon } from 'xterm-addon-fit'
  import { AttachAddon } from 'xterm-addon-attach'
  import { ref, onMounted, onBeforeUnmount } from 'vue'
  //import { connectApi } from '/@/api/utils/connect'
  //import { json } from 'stream/consumers'
  const props = defineProps({
    socketURI: String,
  })
  const formModel = ref({
    server: '172.28.158.98',
    port: '22',
    username: 'root',
    password: 'SyjwljgR&d133',
  })

  let term = null
  let socket = null
  const rows = 1000
  const cols = 160
  let SetOut = false
  let isKey = false

  onMounted(() => {
    // 监听浏览器刷新事件
    window.addEventListener('beforeunload', handleCloseOnRefresh)
  })

  onBeforeUnmount(() => {
    // 移除监听器，防止内存泄露
    window.removeEventListener('beforeunload', handleCloseOnRefresh)
    //不在这里关闭socket
  })

  // 当浏览器刷新时关闭WebSocket连接
  function handleCloseOnRefresh() {
    if (socket) {
      socket.close()
    }
  }
  const connect = async () => {
    if (socket) socket.close()
    if (term) term.dispose()
    initSocket()
  }
  // Xterm主题
  function initTerm() {
    term = new Terminal({
      rendererType: 'canvas', // 渲染类型
      rows: rows, // 行数
      cols: cols, // 设置之后会输入多行之后覆盖现象
      convertEol: true, // 启用时，光标将设置为下一行的开头
      // scrollback: 10,// 终端中的回滚量
      fontSize: 16, // 字体大小
      disableStdin: false, // 是否应禁用输入。
      cursorStyle: 'block', // 光标样式
      // cursorBlink: true, // 光标闪烁
      scrollback: 30,
      tabStopWidth: 4,
      theme: {
        foreground: 'yellow', // 字体
        background: '#060101', // 背景色
        cursor: 'help', // 设置光标
      },
    })

    const attachAddon = new AttachAddon(socket)
    var fitAddon = new FitAddon()
    term.loadAddon(attachAddon)
    term.loadAddon(fitAddon)
    fitAddon.fit()
    term.onResize(({ cols, rows }) => {
      // 调整终端大小
      term.resize(cols, rows)
    })
    term.open(document.getElementById('terminal'))
    term.write('connecting.......')
    term.focus()
    // 限制和后端交互，只有输入回车键才显示结果
    term.prompt = () => {
      term.write('\r\n$ ')
    }
    term.prompt()

    function runFakeTerminal() {
      if (term._initialized) {
        return
      }
      // 初始化
      term._initialized = true
      term.writeln() // 控制台初始化报错处
      term.prompt()

      // 支持输入与粘贴方法
      term.onData(function (key) {
        let order = {
          Data: key,
          Op: 'stdin',
        }
        onSend(order)
      })

      this.term = term
    }

    runFakeTerminal()
  }
  function sendInitialMessage() {
    //构建初始化消息
    const message = JSON.stringify({
      operate: 'connect',
      command: JSON.stringify(formModel.value),
    })
    console.log(message)
    // 发送消息
    socket.send(message)
  }

  // webShell主题
  function initSocket() {
    // const WebSocketUrl = "ws://localhost:8080/ws/ssh";
    const WebSocketUrl = 'ws://172.28.158.98:8085/ws/ssh'
    socket = new WebSocket(WebSocketUrl)
    // webshell链接成功之后操作
    socket.onopen = () => {
      // 发送标记消息
      sendInitialMessage()
      // 链接成功后
      initTerm()
    }

    // webshell关闭之后操作
    socket.onclose = () => {
      console.log('close socket')
    }

    // webshell错误信息
    socket.onerror = () => {
      console.log('socket 链接失败')
    }
  }

  // 特殊处理
  function onSend(data) {
    data = isObject(data) ? JSON.stringify(data) : data
    data = isArray(data) ? data.toString() : data
    data = data.replace(/\\\\/, '\\')
    /*     const sshData = JSON.stringify({
      operate: 'command',
      command: data,
    }) */
    shellWS.onSend(data)
  }

  // 删除左右两端的空格
  function trim(str) {
    return str.replace(/(^\s*)|(\s*$)/g, '')
  }
</script>

<style scoped>
  .header {
    position: fixed; /* 相对于视口的固定位置 */
    width: 100%; /* 宽度占满全屏 */
    z-index: 1; /* 确保它在其他内容之上 */
    background-color: white; /* 你已有的背景颜色 */
  }

  .a-layout-content {
    padding-top: 54px; /* 根据实际头部高度调整此值 */
  }
</style>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
  .xterm-screen {
    min-height: calc(100vh);
  }
</style>
<style scoped>
  h1,
  h2 {
    font-weight: normal;
  }

  ul {
    list-style-type: none;
    padding: 0;
  }

  li {
    display: inline-block;
    margin: 0 10px;
  }

  a {
    color: #42b983;
  }
</style>
